<?php
namespace app\common\service\wechat;

use think\facade\Log;
use think\exception\ValidateException;

class WechatTransfer
{
    /**
     * 单笔转账
     */
    public static function toBalance(array $data): array
    {
        self::validate($data);

        $cfg   = config('wechat');
        $body  = [
            'appid'             => (string)$cfg['appid'],
            'out_bill_no'       => (string)$data['out_no'],
            'transfer_scene_id' => (string)$data['scene_id'] ?? '1000', // 1005=零钱
            'openid'            => (string)$data['openid'],
            'transfer_amount'   => $data['amount'], // 分
            'transfer_remark'   => mb_substr($data['remark'] ?? '转账', 0, 32),
            'notify_url'        => 'https://api.xmrckj.com/api/notify',
            'transfer_scene_report_infos' => [       // 固定传两组
                [
                    'info_type'    => '岗位类型', // 固定值
                    'info_content' => '分销',  // 示例值
                ],
                [
                    'info_type'    => '报酬说明',    // 固定值
                    'info_content' => '佣金', // 示例值
                ],
            ],
        ];

        Log::write('参数' . json_encode($body));

        try {
            $resp = WechatPay::v3Client()
                ->chain('/v3/fund-app/mch-transfer/transfer-bills')
                ->post(['json' => $body]);

            $result = json_decode($resp->getBody(), true);
            Log::write("transfer: {$data['out_no']} " . json_encode($result));
            return $result;
        } catch (\Throwable $e) {
            Log::error("transfer fail: {$data['out_no']} " . json_encode($e->getMessage()));
            throw new ValidateException("微信转账失败：" . $e->getMessage());
        }
    }

    /**
     * 批量转账
     */
    public static function batch(array $list, string $batchNo): array
    {
        $cfg = config('wechatpay');
        $body = [
            'appid'        => $cfg['appid'],
            'out_batch_no' => $batchNo,
            'batch_name'   => mb_substr($list[0]['batch_name'] ?? '批量转账', 0, 32),
            'batch_remark' => mb_substr($list[0]['batch_remark'] ?? '批量转账', 0, 32),
            'total_amount' => array_sum(array_column($list, 'amount')),
            'total_num'    => count($list),
            'transfer_detail_list' => array_map(function ($v) {
                return [
                    'out_detail_no' => $v['out_detail_no'],
                    'transfer_amount' => (int)$v['amount'],
                    'transfer_remark' => mb_substr($v['remark'], 0, 32),
                    'openid'        => $v['openid'],
                ];
            }, $list),
        ];

        $resp = WechatPay::v3Client()
            ->chain('v3/transfer/batches')
            ->post(['json' => $body]);

        return json_decode($resp->getBody(), true);
    }

    /**
     * 主动查询
     */
    public static function query(string $outNo, string $type = 'single')
    {
        $uri = $type === 'single'
            ? "v3/fund-app/mch-transfer/transfer-bills/out-bill-no/{$outNo}?mchid=" . config('wechatpay.mch_id')
            : "v3/transfer/batches/out-batch-no/{$outNo}?need_query_detail=true";
        $resp = WechatPay::v3Client()->chain($uri)->get();
        return json_decode($resp->getBody(), true);
    }

    /**
     * 参数校验
     */
    private static function validate(array &$d)
    {
        if (empty($d['out_no']))  throw new ValidateException('out_no 缺失');
        if (empty($d['openid']))  throw new ValidateException('openid 缺失');
        if (empty($d['amount']) || $d['amount'] < 30) throw new ValidateException('金额最低 0.3 元');
    }
}